package utils

import (
	"fmt"
	"io"
)

/*
**
读取满整个Buffer, 或者返回错误
*/
func ReadFullBuf(reader io.Reader, buf []byte) error {
	l := len(buf)
	idx := 0
	for {
		n, err := reader.Read(buf[idx:])
		if err != nil {
			return err
		}
		idx += n
		if idx+1 >= l {
			return nil
		}
	}
	return nil
}

func ReadUInt16BE(reader io.Reader) (uint16, error) {
	buf := make([]byte, 2)
	err := ReadFullBuf(reader, buf)
	if err != nil {
		return 0, err
	}

	return UInt16_FromBEBytes(buf), nil
}

func ReadLenBuf(reader io.Reader, buf []byte, l int) error {
	return ReadFullBuf(reader, buf[:l])
}

func GetSubBuf(buf []byte, start, l int) []byte {
	// slice[low:high]
	// 从low开始到high 但是不包含high
	if l == 0 {
		return buf[start:]
	}
	return buf[start : start+l]
}

func DoIoCopy(to io.ReadWriteCloser, from io.ReadWriteCloser, count *int64, onerr_func func(err error, io io.ReadWriteCloser),
	deferfunc func(), buffer_func func() []byte, onrecv func(buf []byte)) {

	if deferfunc != nil {
		defer deferfunc()
	}

	if from == nil {
		if onerr_func != nil {
			onerr_func(fmt.Errorf("io:from is null"), from)
			return
		}
	}

	if to == nil {
		if onerr_func != nil {
			onerr_func(fmt.Errorf("io:to is null"), from)
			return
		}
	}
	if buffer_func == nil {
		buffer_func = func() []byte {
			return make([]byte, 1024)
		}
	}
	for {
		buf := buffer_func()
		n, err1 := from.Read(buf)
		if err1 != nil {
			if onerr_func != nil {
				onerr_func(err1, from)
			}
			return
		}
		if count != nil {
			*count += int64(n)
		}
		if onrecv != nil {
			onrecv(buf[:n])
		}
		_, err1 = to.Write(buf[:n])
		if err1 != nil {
			to.Close()
			//if onerr_func != nil {
			//	onerr_func(fmt.Errorf("write dst err:%s", err1.Error()), to)
			//}
			return
		}
	}
}
